package ddz.db.service;

import com.kaka.notice.Proxy;
import com.kaka.notice.annotation.Model;
import com.kaka.util.Charsets;
import com.kaka.util.IntMap;
import ddz.db.redis.JedisFactory;
import ddz.numerical.manager.ConfPlaceInfoManager;
import ddz.numerical.pojo.ConfPlaceInfo;
import ddz.utils.ByteUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import java.util.List;

/**
 * 玩法模式对应的场次游戏人数统计
 */
@Model
public class CensusService extends Proxy {

    private byte[] key(int id) {
        return ("mp:count:" + id).getBytes(Charsets.utf8);
    }

    private IntMap<IntMap<Integer>> query(List<ConfPlaceInfo> confPlaceInfoList) {
        int[] ids = new int[confPlaceInfoList.size()];
        byte[][] keyArray = new byte[confPlaceInfoList.size()][];
        int size = confPlaceInfoList.size();
        for (int i = 0; i < size; i++) {
            ConfPlaceInfo info = confPlaceInfoList.get(i);
            keyArray[i] = key(info.getId());
            ids[i] = info.getId();
        }
        List<Object> result;
        try (Jedis jedis = JedisFactory.getFactory().getJedis()) {
            Pipeline pipeline = jedis.pipelined();
            for (byte[] key : keyArray) {
                pipeline.scard(key);
            }
            result = pipeline.syncAndReturnAll();
        }
        if (result == null || result.isEmpty()) {
            return new IntMap<>(0);
        }
        size = result.size();
        IntMap<IntMap<Integer>> modeMap = new IntMap<>();
        for (int i = 0; i < size; i++) {
            Object obj = result.get(i);
            long amount = obj != null ? (Long) obj : 0;
            int id = ids[i];
            int mode = id / 1000;
            int place = id % 1000;
            IntMap<Integer> placeMap = modeMap.get(mode);
            if (placeMap == null) {
                placeMap = new IntMap<>();
                modeMap.put(mode, placeMap);
            }
            placeMap.put(place, (int) amount);
        }
        return modeMap;
    }

    public IntMap<IntMap<Integer>> query() {
        ConfPlaceInfoManager manager = this.retrieveProxy(ConfPlaceInfoManager.class);
        List<ConfPlaceInfo> confPlaceInfoList = manager.getList();
        if (confPlaceInfoList.isEmpty()) {
            return new IntMap<>(0);
        }
        return query(confPlaceInfoList);
    }

    public IntMap<IntMap<Integer>> query(int mode) {
        ConfPlaceInfoManager manager = this.retrieveProxy(ConfPlaceInfoManager.class);
        List<ConfPlaceInfo> confPlaceInfoList = manager.getListByMode(mode);
        if (confPlaceInfoList == null || confPlaceInfoList.isEmpty()) {
            return new IntMap<>(0);
        }
        return query(confPlaceInfoList);
    }

    public void plus(int mode, int place, long uid) {
        ConfPlaceInfoManager manager = this.retrieveProxy(ConfPlaceInfoManager.class);
        int id = manager.isExists(mode, place);
        if (id <= 0) return;
        byte[] key = key(id);
        byte[] val = ByteUtils.getBytes(uid);
        try (Jedis jedis = JedisFactory.getFactory().getJedis()) {
            jedis.sadd(key, val);
        }
    }

    public void reduce(int mode, int place, long uid) {
        ConfPlaceInfoManager manager = this.retrieveProxy(ConfPlaceInfoManager.class);
        int id = manager.isExists(mode, place);
        if (id <= 0) return;
        byte[] key = key(id);
        byte[] val = ByteUtils.getBytes(uid);
        try (Jedis jedis = JedisFactory.getFactory().getJedis()) {
            jedis.srem(key, val);
        }
    }

    public void reduce(int mode, int place, List<Long> uids) {
        ConfPlaceInfoManager manager = this.retrieveProxy(ConfPlaceInfoManager.class);
        int id = manager.isExists(mode, place);
        if (id <= 0) return;
        if (uids.isEmpty()) return;
        byte[] key = key(id);
        int size = uids.size();
        byte[][] valArray = new byte[size][];
        for (int i = 0; i < size; i++) {
            valArray[i] = ByteUtils.getBytes(uids.get(i));
        }
        try (Jedis jedis = JedisFactory.getFactory().getJedis()) {
            jedis.srem(key, valArray);
        }
    }

}
